/**
 * Copyright (2017, ) Institute of Software, Chinese Academy of Sciences
 */
package cn.abcsys.cloud.devops.runtime.incubates;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import cn.abcsys.cloud.devops.runtime.incubates.models.App;
import cn.abcsys.cloud.devops.runtime.incubates.models.Ngx;
import cn.abcsys.cloud.devops.runtime.incubates.models.Url;
import cn.abcsys.cloud.devops.runtime.incubates.utils.IOUtils;

/**
 * @author wuheng(wuheng@otcaix.iscas.ac.cn)
 * @date   Jul 10, 2017
 *
 */
public class AppDetector extends Thread {

	protected final static Logger m_logger= Logger.getLogger(App.class); 
	
	/**
	 * 被管理的Nginx实例
	 */
	protected final Ngx nginx;
	
	/**
	 * 
	 */
	protected boolean updateNginxConfig = false;
	
	/**
	 * 初始化
	 * 
	 * @param nginx
	 */
	public AppDetector(Ngx nginx) {
		if(nginx == null) {
			throw new RuntimeException("nginx is null.");
		}
		this.nginx = nginx;
	}

	@Override
	public void run() {
		while(true) {
			setUpdateNginxConfig(false);
			createNginxConfig();
			updateNginxConfigIfNeed();
			waitFor5Secends();
		}
	}

	private void waitFor5Secends() {
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
		}
	}

	private void updateNginxConfigIfNeed() {
		if(updateNginxConfig) {
			try {
				Ngx config = (Ngx) nginx.clone();
				// call modify ngx config basd on Thread-based 
			} catch (CloneNotSupportedException e) {
				m_logger.error(e.getMessage());
			}
		}
	}

	private void createNginxConfig() {
		for(App application : nginx.getApps()) {
			List<String> hosts = queryHostsBy(application);
			for (Integer port : application.getPorts()) {
				if(application.getUrl(port).addHostsIfExistNew(hosts)) {
					setUpdateNginxConfig(true);
				}
			}
		}
	}

	private List<String> queryHostsBy(App application)  {
		
		List<String> hosts = new ArrayList<String>();
		try {
			String commnad = createQueryCommand(application);
			execQueryCommand(hosts, commnad);
		} catch (Exception e) {
			// this is ok.
		}
		return hosts;
	}

	
	
	private void execQueryCommand(List<String> hosts, String commnad) throws Exception {
		Process process = Runtime.getRuntime().exec(commnad);
		BufferedReader br = IOUtils.createBufferedReader(process);
		String line = null;
		while((line=br.readLine())!=null){
			hosts.add(line);
		}
		IOUtils.closeBufferedReader(br);
	}

	private static String createQueryCommand(App application) {
		String commnad = "/bin/bash " 
				+ AppDetector.class.getResource("detector.sh").getPath()
				+ " " + application.getRuntime()
				+ " " + application.getName();
		return commnad;
	}

	
	public boolean isUpdateNginxConfig() {
		return updateNginxConfig;
	}

	public void setUpdateNginxConfig(boolean updateNginxConfig) {
		this.updateNginxConfig = updateNginxConfig;
	}

	public static void main(String[] args) throws IOException, InterruptedException {
		// 添加Nginx主机时进行实例化
		Ngx nginx = new Ngx("127.0.0.1", "admin", "admin");
		// 添加负载均衡时候传递 Name, kube-master Ip和Urls
		App app1 = new App("test000-kubernetes-20170710212250686", "40.125.203.202");
		app1.addUrl(8080, new Url("/home"));
		app1.addUrl(7080, new Url("/root"));
		nginx.addApp(app1);
		
		App app2 = new App("test000-kubernetes-20170710213848816", "40.125.203.202");
		app2.addUrl(6000, new Url("/goog"));
		nginx.addApp(app2);
		
		AppDetector detector = new AppDetector(nginx);
		detector.start();
		
		while(true) {
			for(App app : nginx.getApps()) {
				System.out.println(app.getName());
				for (Integer port : app.getPorts()) {
					Url url = app.getUrl(port);
					System.out.println("\t" + port + url.getUrl());
					for(String host : url.getHosts()) {
						System.out.println("\t\t" + host);
					}
				}
		 	}
			Thread.sleep(5000);
		}
	}
}
